#include "maze.h"

std::ostream&  operator<< (std::ostream&  s, const Maze & M){
    for(int i = 0; i < M.row; i++){
        for(int j = 0; j < M.col; j++){
            if(i == M.Inicial.row && j == M.Inicial.col)
               s << "i ";
            else if (i == M.Final.row && j == M.Final.col)
                s << "f ";
            else
                s << M.Vec[M.col*i + j] << " ";
        }
        s << std::endl;
    }
    return s;
}

Maze & Maze::operator=(const Maze &b){
    if(Vec != NULL) free(Vec);
    col = b.col;
    row = b.row;
    Inicial = b.Inicial;
    Final = b.Final;
    Vec = (short int *) malloc(sizeof(short int) * col * row);
    memcpy(Vec,b.Vec,sizeof(short int) * col * row);
    setSaddles(Inicial.row,Inicial.col,INIT);
    setSaddles(Final.row,Final.col,END);
    return *this;
}

Maze::Maze(Node Inicial_, Node Final_,int row_,int col_)
{
    col = col_;
    row = row_;
    Final = Final_;
    Inicial = Inicial_;
    Vec = (short int *) malloc(sizeof(short int) * col * row);
    memset(Vec,0,sizeof(short int) * col * row);
    setSaddles(Inicial.row,Inicial.col,INIT);
    setSaddles(Final.row,Final.col,END);
}


Maze::Maze(int row_,int col_) {
    col = col_;
    row = row_;
    if(col * row != 0)
        Vec = (short int *) malloc(sizeof(short int) * col * row);
    else
        Vec = NULL;
    memset(Vec,0,sizeof(short int) * col * row);
}

void Maze::setInicial(Node Inicial_){
    int rowTmp = Inicial.row;
    int colTmp = Inicial.col;
    Inicial = Inicial_;
    setSaddles(rowTmp,colTmp,EMPTY);
    setSaddles(Inicial.row,Inicial.col,INIT);
}
void Maze::setFinal(Node Final_){
    int rowTmp = Final.row;
    int colTmp = Final.col;
    Final = Final_;
    setSaddles(rowTmp,colTmp,EMPTY);
    setSaddles(Final.row,Final.col,END);
}

Maze::Maze() {
    col = 0;
    row = 0;
    Vec = NULL;
}


Maze::~Maze(){ 
    if(Vec != NULL) free(Vec);
    Vec = NULL;
}

int Maze::setSaddles(int row_,int col_,LAB t) {
    if(col_ < 0 || row_ < 0)
        return 0;
    if(row_ * col + col_ > col * row)
        return 0;

    if((Inicial.row == row_ && Inicial.col == col_ && t != INIT) ||
       (Final.col == col_ && Final.row == row_ && t != END))
        return 0;
    Vec[row_ * col + col_] = t;
    return 1;
}

short int Maze::getSaddles(int row_,int col_) {
    return Vec[row_ * col + col_];
}

int Maze::setSolution(int row_,int col_) {
    if(col_ * row_ > col * row || Vec == NULL)
        return 0;
    if(Vec[row_ * col + col_] == INIT || Vec[row_ * col + col_] == END)
        return 0;

    Vec[row_ * col + col_] = PAS;
    return 1;
}

short int Maze::getPos(int i) {
    return Vec[i];
}

void Maze::Rand() {
    for(int i = 0; i < 600; i++)
        this->setSaddles(rand() % this->row,rand() % this->col,WALL);
}


Node Maze::getInicial() {
    return Inicial;
}

Node Maze::getFinal() {
    return Final;
}
